
package com.wd.base.thread;

import com.wd.base.util.Logger;

import java.lang.ref.WeakReference;

/**
 * <自动释放 Runnable>
 *
 * @author wangnaiwen
 * @version [V1.0.0.0, 2020/5/23]
 * @since V1.0.0.0
 */
public abstract class AutoReleaseRunnable implements Runnable {
    private static final String TAG = "AutoReleaseRunnable";

    private final WeakReference<AutoReleaseRunnable> ref;

    public AutoReleaseRunnable(AutoReleaseNestedHolder holder) {
        if (holder == null) {
            this.ref = null;
            Logger.i("AutoReleaseRunnable", "deposit holder is null");
        } else {
            holder.deposit(this);
            this.ref = new WeakReference(this);
        }
    }

    static Runnable transfer(Runnable runnable) {
        WeakReference<AutoReleaseRunnable> ref =
            runnable instanceof AutoReleaseRunnable ? ((AutoReleaseRunnable) runnable).getRef() : null;
        return (Runnable) (ref == null ? runnable : new AutoReleaseRunnableWrapper(runnable));
    }

    private WeakReference<AutoReleaseRunnable> getRef() {
        return this.ref;
    }

    private static final class AutoReleaseRunnableWrapper implements Runnable {
        private final WeakReference<AutoReleaseRunnable> autoReleaseRunnableRef;

        private AutoReleaseRunnableWrapper(Runnable runnable) {
            this.autoReleaseRunnableRef =
                runnable instanceof AutoReleaseRunnable ? ((AutoReleaseRunnable) runnable).getRef() : null;
        }

        public void run() {
            if (this.autoReleaseRunnableRef != null) {
                AutoReleaseRunnable runnable = (AutoReleaseRunnable) this.autoReleaseRunnableRef.get();
                if (runnable != null) {
                    runnable.run();
                } else {
                    Logger.i(TAG, "runnable is released");
                }
            }

        }
    }
}
